<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
//include_once 'base.php';

require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/layout.class.php';


/**
 * Constructs a Widget_GridLayout.
 *
 * @param int		$nbColumns	The number of columns in the grid
 * @param string	$id			The item unique id.
 * @return Widget_GridLayout
 */
function Widget_GridLayout($nbColumns = null, $id = null)
{
	return new Widget_GridLayout($nbColumns, $id);
}


/**
 * The Widget_GridLayout class provides a way to arrange widgets/items in a grid.
 *
 */
class Widget_GridLayout extends Widget_Layout implements Widget_Displayable_Interface
{

	private $_nbColumns = -1;

	/**
	 *
	 * @var Widget_TableView
	 */
	protected $_table = null;

	protected $_sectionLabels = array('' => null);
	protected $_sectionClasses = array('' => null);
	protected $_sectionOptions = array('' => null);
	

	protected $_sections = array('' => array());

	/**
	 * The current section id.
	 * @var string
	 */
	private $_currentSection;

	/**
	 * @param int    $nbColumns Number of columns in the grid.
	 * @param string $id        The item unique id.
	 *
	 * @return Widget_GridLayout
	 */
	public function __construct($nbColumns = null, $id = null)
	{
		parent::__construct($id);

		if (isset($nbColumns)) {
			$this->setNbColumns($nbColumns);
		}

		$this->_currentRow = 0;
		$this->_currentCol = 0;
		$this->_currentSection = '';
	}


	/**
	 * @param Widget_TableView $table
	 *
	 * @return Widget_GridLayout
	 */
	public function setTableView(Widget_TableView $table = null)
	{
		$this->_table = $table;
		return $this;
	}

	/**
	 * Get cell content or null if empty
	 * @return Widget_Item
	 */
	public function getCell($row, $col)
	{
		if (isset($this->_sections[$this->_currentSection][$row][$col])) {
			return $this->_sections[$this->_currentSection][$row][$col];
		}

		return null;
	}


	/**
	 * Sets number of columns in the grid.
	 *
	 * @return Widget_GridLayout
	 */
	public function setNbColumns($nbColumns)
	{
		$this->_nbColumns = $nbColumns;
		return $this;
	}



	/**
	 * Creates a new section in the layout.
	 *
	 * @param string	$id				The unique identifier (for the layout) of the new section.
	 * @param string	$label			An optional text label.
	 * @param string	$className		An optional class name.
	 *
	 * @return Widget_GridLayout
	 */
	public function addSection($id, $label = null, $className = null)
	{
		$this->_sections[$id] = array();
		$this->_sectionOptions[$id] = array();
		
		$this->_sectionLabels[$id] = $label;
		$this->_sectionClasses[$id] = $className;

		return $this;
	}


	/**
	 * Sets the current section to which subsquent addItem call will add items.
	 *
	 * @param string	$id		The identifier of the section (previously added by @see addSection).
	 * @return Widget_GridLayout
	 */
	public function setCurrentSection($id)
	{
		$this->_currentSection = $id;
		return $this;
	}




	/**
	 * Adds $item to this layout.
	 * The position in the grid, as well as the spanning in the grid can be specified.
	 *
	 * @param Widget_Item	$item
	 * @param int		$row
	 * @param int		$col
	 * @param int		$rowSpan
	 * @param int		$colSpan
	 * @return Widget_GridLayout
	 */
	public function addItem(Widget_Displayable_Interface $item, $row = -1, $col = -1, $rowSpan = -1, $colSpan = -1)
	{
//		assert('is_int($row); /* The "row" parameter must be an int. */');
//		assert('is_int($col); /* The "col" parameter must be an int. */');
//		assert('is_int($rowSpan); /* The "rowSpan" parameter must be an int. */');
//		assert('is_int($colSpan); /* The "colSpan" parameter must be an int. */');
		parent::addItem($item);

		$this->_sections[$this->_currentSection][$row][$col] = $item;
		
		if ($colSpan > -1) {
			$this->_sectionOptions[$this->_currentSection][$row][$col]['colspan'] = $colSpan;
		}
		if ($rowSpan > -1) {
			$this->_sectionOptions[$this->_currentSection][$row][$col]['rowspan'] = $rowSpan;
		}
		if ($col > $this->_nbColumns - 1) {
			$this->_nbColumns = $col + 1;
		}
		return $this;
	}


	/**
	 * Adds $item to this layout.
	 * The position in the grid, as well as the spanning in the grid can be specified.
	 *
	 * @param array			$item
	 * @param int			$row
	 * @param int			$col
	 * @param int			$rowSpan
	 * @param int			$colSpan
	 * @return Widget_GridLayout
	 */
	public function addRow($items, $row = -1)
	{
//		assert('is_array($items); /* The "items" parameter must be an array. */');
//		assert('is_int($row); /* The "row" parameter must be an int. */');
		$col = 0;
		foreach ($items as $item) {
			$this->addItem($item, $row, $col++);
		}

		return $this;
	}


	/**
	 * (non-PHPdoc)
	 * @see programs/widgets/Widget_Layout#getClasses()
	 */
	public function getClasses()
	{
		$classes = parent::getClasses();
		$classes[] = 'widget-layout-grid';
		return $classes;
	}

	/**
	 * @param	int		$columnId
	 * @return array
	 */
	private function getColumnClasses($columnId, Widget_Displayable_Interface $cellContent)
	{
		if (!isset($this->_table)) {
			return array();
		}

		return $this->_table->getColumnClasses($columnId, $cellContent);
	}

	/**
	 * @param	int		$rowId
	 * @return array
	 */
	private function getRowClasses($rowId)
	{
		if (!isset($this->_table)) {
			return array();
		}

		return $this->_table->getRowClasses($rowId);
	}



	/**
	 * (non-PHPdoc)
	 * @see programs/widgets/Widget_Layout#display($canvas)
	 */
	public function display(Widget_Canvas $canvas)
	{

		require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/label.class.php';

		$sections = array();

		foreach ($this->_sections as $sectionId => &$section) {
			if (count($section) == 0) {
				continue;
			}
			$rows = array();
			if (isset($this->_sectionLabels[$sectionId])) {
				$cells = array();
				$opt = Widget_Item::Options();
				$opt->span = $this->_nbColumns;
				$cells[] = $canvas->gridRowCell(null, array($this->_sectionClasses[$sectionId]), array($this->_sectionLabels[$sectionId]), $opt);
				$rows[] = $canvas->gridRow(null, array('widget-table-section-header'), $cells);
			}
			foreach ($section as $rowId => $itemRow) {
				$cells = array();
				foreach ($itemRow as $colId => $item) {

					$colSpan = isset($this->_sectionOptions[$sectionId][$rowId][$colId]['colspan'])
						? $this->_sectionOptions[$sectionId][$rowId][$colId]['colspan']
						: null;
					$rowSpan = isset($this->_sectionOptions[$sectionId][$rowId][$colId]['rowspan'])
						? $this->_sectionOptions[$sectionId][$rowId][$colId]['rowspan']
						: null;
					$cells[] = $canvas->gridRowCell(null, $this->getColumnClasses($colId, $item), array($item), null, $rowSpan, $colSpan);
				}
				$rows[] = $canvas->gridRow(null, $this->getRowClasses($rowId), $cells);
			}
			$sections[] = $canvas->gridSection('header_section' . $sectionId, array('widget-table-section', $this->_sectionClasses[$sectionId]), $rows);
		}

		return $canvas->grid($this->getId(), $this->getClasses(), $sections, array(), $this->getCanvasOptions());
	}

}

